#include "head.h"
// v 1.0 小文件
//int transFile(int sockfd){
//    send(sockfd,"file1",5,0);
//    int fd = open("file1",O_RDWR);
//    char buf[4096] = {0};
//    ssize_t sret = read(fd,buf,sizeof(buf));
//    send(sockfd,buf,sret,0);
//    return 0;
//}
// v 2.0 使用小火车的小文件
typedef struct train_s {
    int length;
    char data[1000]; // 1000是上限不是实际值
} train_t;
//int transFile(int sockfd){
//    train_t train;
//    train.length = 5;
//    memcpy(train.data,"file1",5);
//    send(sockfd,&train,sizeof(int)+train.length,0);
//
//    int fd = open("file1",O_RDWR);
//    ssize_t sret = read(fd,train.data,sizeof(train.data));
//    train.length = sret;
//    send(sockfd,&train,sizeof(int)+train.length,0);
//    return 0;
//}
// v 3.0 使用小火车的大文件
//int transFile(int sockfd){
//    train_t train;
//    train.length = 5;
//    memcpy(train.data,"file1",5);
//    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
//
//    int fd = open("file1",O_RDWR);
//    while(1){
//        ssize_t sret = read(fd,train.data,sizeof(train.data));
//        train.length = sret;
//        send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
//        if(sret == 0){
//            break;
//        }
//    }
//    return 0;
//}
// v4.0 显示进度条
//int transFile(int sockfd){
//    train_t train;
//    train.length = 5;
//    memcpy(train.data,"file1",5);
//    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
//
//    int fd = open("file1",O_RDWR);
//    struct stat statbuf;
//    fstat(fd,&statbuf);
//    memcpy(train.data,&statbuf.st_size,sizeof(off_t));
//    train.length = sizeof(off_t);
//    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
//
//    while(1){
//        ssize_t sret = read(fd,train.data,sizeof(train.data));
//        train.length = sret;
//        send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
//        if(sret == 0){
//            break;
//        }
//    }
//    return 0;
//}
//v 4.1 服务端使用mmap
//int transFile(int sockfd){
//    train_t train;
//    train.length = 5;
//    memcpy(train.data,"file1",5);
//    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
//
//    int fd = open("file1",O_RDWR); // O_RDWR
//    struct stat statbuf;
//    fstat(fd,&statbuf);
//    memcpy(train.data,&statbuf.st_size,sizeof(off_t));
//    train.length = sizeof(off_t);
//    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
//
//    char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,
//                           fd, 0);
//    off_t totalSize = 0;
//    while(totalSize < statbuf.st_size){
//        if(statbuf.st_size - totalSize > 1000){
//            train.length = 1000;
//        }
//        else{
//            train.length = statbuf.st_size - totalSize;
//        }
//        send(sockfd,&train.length,sizeof(int),MSG_NOSIGNAL);
//        send(sockfd,p+totalSize,train.length,MSG_NOSIGNAL);
//        totalSize += train.length;
//    }
//    train.length = 0;
//    send(sockfd,&train.length,sizeof(int),MSG_NOSIGNAL);
//    munmap(p,statbuf.st_size);
//    return 0;
//}
//v5.0 一次性发送
#include <sys/sendfile.h>
int transFile(int sockfd){
    train_t train;
    train.length = 5;
    memcpy(train.data,"file1",5);
    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);

    int fd = open("file1",O_RDWR); // O_RDWR
    struct stat statbuf;
    fstat(fd,&statbuf);
    memcpy(train.data,&statbuf.st_size,sizeof(off_t));
    train.length = sizeof(off_t);
    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);

    //char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,
    //                       fd, 0);
    //send(sockfd,p,statbuf.st_size,MSG_NOSIGNAL);
    //munmap(p,statbuf.st_size);
    sendfile(sockfd,fd,NULL,statbuf.st_size);
    return 0;
}
